package info.ask4research.web;

import info.ask4research.model.Graph;
import info.ask4research.model.UnitOfLearning;
import info.ask4research.model.activities.Activity;
import info.ask4research.model.activities.LearningActivity;
import info.ask4research.model.activities.OneToTwoActivity;
import info.ask4research.model.activities.SupportActivity;
import info.ask4research.service.IActivityService;
import info.ask4research.service.IGraphService;
import info.ask4research.service.IUnitOfLearningService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONArray;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class GraphController {

	private IGraphService graphService;
	private IActivityService activityService;
	private IUnitOfLearningService unitOfLearningService;
	
	
	@RequestMapping(value="jsp/graph/removedSA.action")
	public @ResponseBody void removeSupportActivity(@RequestParam(value="htmlCode") String htmlCode,
			@RequestParam(value="activityId") String activityId,
			HttpSession session) throws Exception {
		UnitOfLearning unitOfLearning = unitOfLearningService.get((Integer)session.getAttribute("unitOfLearningId"));
		if(StringUtils.isNotEmpty(htmlCode)){
			Graph graph = graphService.getByHtmlCode(htmlCode);
			
			//if(graph==null){
			//	unitOfLearning.setGraph(null);
			//	unitOfLearning = unitOfLearningService.save(unitOfLearning);
			//	graphService.remove(graph);
			//}
			session.setAttribute("graphId", activityId);
			//graph.setGraphHtml(htmlCode);
			//graph = graphService.save(graph);
			String[] activityType = activityId.split(":");
			Activity activity = activityService.getbyGraphId(activityType[1]);
			//unitOfLearning.removeActivity(activity);
			//unitOfLearning = unitOfLearningService.save(unitOfLearning);
			activityService.remove(activity);
			
		}

	}
	
	
	@RequestMapping(value="jsp/graph/save.action")
	public @ResponseBody Map saveAfterActivityCreation(@RequestParam(value="htmlCode") String htmlCode,
			@RequestParam(value="activityId") String activityId,
			HttpSession session) throws Exception {
		UnitOfLearning unitOfLearning = unitOfLearningService.get((Integer)session.getAttribute("unitOfLearningId"));
		if(StringUtils.isNotEmpty(htmlCode)){
			Graph graph = graphService.getByHtmlCode(htmlCode);
			if(graph==null){
				graph = new Graph();
			}
			session.setAttribute("graphId", activityId);
			graph.setGraphHtml(htmlCode);
			graph = graphService.save(graph);
			String[] activityType = activityId.split(":");
			Activity activity = activityService.getbyGraphIdAndUoLId(activityType[1], unitOfLearning.getId());
			if(activity != null){
				List<Activity> activities = unitOfLearningService.getActivities(unitOfLearning.getId());
				List<Integer> actIntegers = new ArrayList<Integer>();
				for(Activity activ : activities){
					actIntegers.add(activ.getId());
				}
				if(!actIntegers.contains(activity.getId())){
					unitOfLearning.addActivity(activity);	
				}
			}else {
				if("Activity".equals(activityType[0])){
					activity = new LearningActivity();
					activity.setActivityGraphId(activityType[1]);
					activity = activityService.save(activity);
					unitOfLearning.addActivity(activity);
				} else if ("Support".equals(activityType[0])){
					activity = new SupportActivity();
					activity.setActivityGraphId(activityType[1]);
					activity = activityService.save(activity);
					unitOfLearning.addActivity(activity);
				} else{
					activity = new OneToTwoActivity();
					activity.setActivityGraphId(activityType[1]);
					((OneToTwoActivity) activity).setSelectedUser(null);
					activity = activityService.save(activity);
					unitOfLearning.addActivity(activity);
				}
			}
			unitOfLearning.setGraph(graph);
			unitOfLearningService.save(unitOfLearning);
			Map<String,Object> modelMap = new HashMap<String,Object>(3);
			activity.setAddons(null);
			activity.setFiles(null);
			activity.setTams(null);
			if(!StringUtils.isEmpty(activity.getDescription()) && activity.getDescription().startsWith("?")){
				activity.setDescription(activity.getDescription().substring(0,0)+activity.getDescription().substring(0+1));
			}
			
			if(activity instanceof LearningActivity){
				if(!StringUtils.isEmpty(((LearningActivity) activity).getDescriptionObjective()) && ((LearningActivity) activity).getDescriptionObjective().startsWith("?")){
					((LearningActivity) activity).setDescriptionObjective(((LearningActivity) activity).getDescriptionObjective().substring(0,0)+((LearningActivity) activity).getDescriptionObjective().substring(0+1));
				}
				if(!StringUtils.isEmpty(((LearningActivity) activity).getDescriptionPrerequisites()) && ((LearningActivity) activity).getDescriptionPrerequisites().startsWith("?")){
					((LearningActivity) activity).setDescriptionPrerequisites(((LearningActivity) activity).getDescriptionPrerequisites().substring(0,0)+((LearningActivity) activity).getDescriptionPrerequisites().substring(0+1));
				}
			}
			modelMap.put("act", activity);
			modelMap.put("success", true);
			return modelMap;
		}else{
			Map<String,Object> modelMap = new HashMap<String,Object>(3);
			modelMap.put("success", false);
			return modelMap;
		}

	}
	
	@RequestMapping(value="jsp/graph/saveGraph.action")
	public @ResponseBody Map saveGraph(@RequestParam(value="htmlCode") String htmlCode,
			HttpSession session) throws Exception {
		UnitOfLearning unitOfLearning = unitOfLearningService.get((Integer)session.getAttribute("unitOfLearningId"));
		if(StringUtils.isNotEmpty(htmlCode)){
			Graph graph = graphService.getByHtmlCode(htmlCode);
			if(graph==null){
				graph = new Graph();
			}
			graph.setGraphHtml(htmlCode);
			graph = graphService.save(graph);

			unitOfLearning.setGraph(graph);
			unitOfLearningService.save(unitOfLearning);
			Map<String,Object> modelMap = new HashMap<String,Object>(3);
			modelMap.put("success", true);
			return modelMap;
		}else{
			Map<String,Object> modelMap = new HashMap<String,Object>(3);
			modelMap.put("failed", true);
			return modelMap;
		}

	}

	@RequestMapping(value="jsp/graph/view.action")
	public @ResponseBody Map view(@RequestParam(value="limit") int limit,
			@RequestParam(value="page") int page,
			@RequestParam(value="start") int start,
			HttpServletRequest request,
            HttpServletResponse response,
            HttpSession session) throws Exception {

		List<Graph> graphs = graphService.getPaginated(limit,page,start);
		List<Graph> repatternGraph = new ArrayList<Graph>();
		for(Graph graph: graphs){
			String code = graph.getGraphHtml();
			code = replaceAllWords(code, "&quot;", "\"");
			Graph g = new Graph();
			g.setId(graph.getId());
			g.setGraphHtml(code);
			repatternGraph.add(g);
		}
		
		JSONArray jsonArray = JSONArray.fromObject(repatternGraph);
		List<Graph> newContacts = (List<Graph>) JSONArray.toCollection(jsonArray,Graph.class);
		Map<String,Object> modelMap = new HashMap<String,Object>(3);
		if(!modelMap.isEmpty()){
			modelMap.put("title", repatternGraph.get(0).getId());
			modelMap.put("total", repatternGraph.size());
			modelMap.put("items", newContacts);
			modelMap.put("success", true);
		}
		return modelMap;


	}

	static String replaceAllWords(String original, String find, String replacement) {
		Pattern pattern = Pattern.compile(find);
		
		        //
		        // Creates a matcher that will match the given input against the pattern
		        //
		        Matcher matcher = pattern.matcher(original);
		 
		        //
		        // Replaces every subsequence of the input sequence that matches the
		        // pattern with the given replacement string
		        //
		        String output = matcher.replaceAll(replacement);
		        
		        return output;
	}

	public IGraphService getGraphService() {
		return graphService;
	}
	@Resource(name="graphService")
	public void setGraphService(IGraphService graphService) {
		this.graphService = graphService;
	}
	public IUnitOfLearningService getUnitOfLearningService() {
		return unitOfLearningService;
	}
	@Resource(name="unitOfLearningService")
	public void setUnitOfLearningService(
			IUnitOfLearningService unitOfLearningService) {
		this.unitOfLearningService = unitOfLearningService;
	}
	public IActivityService getActivityService() {
		return activityService;
	}
	@Resource(name="activityService")
	public void setActivityService(IActivityService activityService) {
		this.activityService = activityService;
	}

} 
